core = get_core()
--variables estaticas
g_speed=10.0
PI=3.1416


g_dead=false

--variables de salto
g_bJumping=false
g_time_accum=0.0
g_hAccum=0

--datos para calculo de salto
--inicializacion
g_vertical_init_pos=Vect3f(0.0,1.0,0.0)
--constantes
g_jumping_speed=7
g_jump_time=1
g_top_height=(g_jumping_speed*(g_jump_time/2))+(5*(g_jump_time/2)*(g_jump_time/2))

--Variables estáticas para el movimiento de plataformas
g_prev_platform_pos=Vect3f(0.0,0.0,0.0) 
g_bOn_platform=false
-----------------------

function on_create_3d_scene()

	core:get_renderable_objects_layers_manager():get_resource("solid"):add_scripted_controller("my_object", Vect3f(0.0, 1.0, 0.0))
	local l_box_object=core:get_renderable_objects_layers_manager():get_resource("solid"):get_instance("Box001")
	core:get_renderable_objects_layers_manager():get_resource("solid"):get_instance("my_object"):set_position(l_box_object:get_position())
	
	core:get_renderable_objects_layers_manager():get_resource("solid"):get_instance("my_object"):set_yaw(PI/2);
	
	core:get_renderable_object_track_player_manager():get_resource("ROTP1"):play_track()
	core:get_renderable_object_track_player_manager():get_resource("ROTP2"):play_track()
	core:get_renderable_object_track_player_manager():get_resource("ROTP3"):play_track()
end


function on_update_scripted_controller()
	
	desplazamiento()
	floor_check()
	local l_im=core:get_input_manager()
	if(l_im:is_down(0,CInputManager.KEY_H))then
		core:get_renderable_objects_layers_manager():get_resource("solid"):get_instance("ParedQueSeMueve"):set_position(Vect3f(0.0,0.0,0.0))
	end
	
end

--FUNCIONES PARA SALTO Y DESPLAZAMIENTO DEL PERSONAJE
--Función de salto que determina la posición "y" del player durante el salto
function jump()
	
	local l_dt=core:get_elapsed_time()
	g_time_accum=g_time_accum+l_dt
	local init_y=g_vertical_init_pos.y
	
	local curr_vertical_speed=g_jumping_speed-(10.0*g_time_accum)
	g_hAccum=g_hAccum+(curr_vertical_speed*l_dt)
	local curr_y=init_y+g_hAccum
	
	if (g_hAccum>=g_top_height or g_hAccum<0) then
		curr_vertical_speed=10*(g_time_accum-(g_jump_time/2))
		curr_y=(init_y+g_top_height)-(10.0*curr_vertical_speed)
	end
	
	if (curr_y<=init_y) then
		curr_y=init_y
		g_hAccum=0.0
		g_time_accum=0.0
		g_bJumping=false
		g_speed=10.0	
	end
	
	return curr_y
	--return init_y
end

--Desplazamiento del player
function desplazamiento()
	local l_im=core:get_input_manager()
	--local l_player=core:get_renderable_objects_layers_manager():get_resource("solid"):get_instance("Box001")
	local l_player=core:get_renderable_objects_layers_manager():get_resource("solid"):get_instance("my_object")
	local l_box_object=core:get_renderable_objects_layers_manager():get_resource("solid"):get_instance("Box001")
	local l_dt=core:get_elapsed_time()
	
	--movimiento de camara con mouse
	local l_dm=l_im:get_mouse_delta()

	
	local l_yaw=	l_player:get_yaw()-(l_dm.x*0.01)
	local l_pitch=	l_player:get_pitch()+(l_dm.y*0.01)

	
	--Set de ángulo para cámara y objeto
	if(l_im:is_down(5,0)) then
	
		l_player:set_yaw(l_yaw)
		l_box_object:set_yaw(-l_yaw+(PI/2))
		l_player:set_pitch(l_pitch)
	end
	-------------------------------------------------------
	
	local l_cpos=l_player:get_position()
	local l_pos=Vect3f(l_cpos)
	
	--Vector que dirige el movimiento
	local l_dir=Vect3f(lua_cos(l_yaw),0.0,lua_sin(l_yaw));
	--Vector para el movimiento lateral (strafe)
	l_dir_strafe=lua_cross_product(l_dir,Vect3f(0.0,1.0,0.0));
	--Vector director para el desplazamiento en diagonal
	l_2dir=l_dir+l_dir_strafe
	l_2dir=l_2dir:get_normalized(1.0)
	
	--Movimientos con A,S,W,D
	if(l_im:is_down(0,CInputManager.KEY_D) and l_im:is_down(0,CInputManager.KEY_W)) 	then		l_pos=(l_pos-((l_2dir:rotate_y(-PI/2))*g_speed*l_dt))	
	elseif(l_im:is_down(0,CInputManager.KEY_D) and l_im:is_down(0,CInputManager.KEY_S)) then		l_pos=(l_pos-(l_2dir*g_speed*l_dt)) 					
	elseif(l_im:is_down(0,CInputManager.KEY_A) and l_im:is_down(0,CInputManager.KEY_S)) then		l_pos=(l_pos-((l_2dir:rotate_y(PI/2))*g_speed*l_dt)) 	
	elseif(l_im:is_down(0,CInputManager.KEY_A) and l_im:is_down(0,CInputManager.KEY_W)) then		l_pos=(l_pos-((l_2dir:rotate_y(PI))*g_speed*l_dt)) 		
	---------------------------------------------------
	elseif(l_im:is_down(0,CInputManager.KEY_W)) then		l_pos=(l_pos+(l_dir*g_speed*l_dt)) 
	elseif(l_im:is_down(0,CInputManager.KEY_S)) then		l_pos=(l_pos-(l_dir*g_speed*l_dt)) 
	elseif(l_im:is_down(0,CInputManager.KEY_D)) then		l_pos=(l_pos-(l_dir_strafe*g_speed*l_dt)) 
	elseif(l_im:is_down(0,CInputManager.KEY_A)) then		l_pos=(l_pos+(l_dir_strafe*g_speed*l_dt)) end
	------------------------------------------------------------------------------------------------------------
	
	
	
	
	
	--Desplazamiento vertical
	-- local l_up_n_down=Vect3f(0.0,1.0,0.0)
	-- if(l_im:is_down(0,CInputManager.KEY_I)) then		l_pos=(l_pos+(l_up_n_down*g_speed*l_dt)) end
	-- if(l_im:is_down(0,CInputManager.KEY_K)) then		l_pos=(l_pos-(l_up_n_down*g_speed*l_dt)) end
	--------------------------------------------
	
	
	
	--Verifica si está saltando para anular salto doble
	if(l_im:is_up_down(0,CInputManager.KEY_SPACE) and g_bJumping ==false) then
		g_bJumping=true 
		--g_vertical_init_pos=l_pos.y --esta línea está comentada por un bug que genera y no tengo idea de porq
		
	end
	
	--Verifica si el personaje saltó para ejecutar la función de salto
	if	g_bJumping==true then
		g_speed=5
		l_pos.y=jump()
	end
	
	
	if (g_dead)then--Verifico si el personaje está muerto
		--Si es así reseteo posición
		if (l_pos.z>95) then
			l_player:set_position(Vect3f(0.0,1.0,95.0))--para probar plataformas
		else
			l_player:set_position(Vect3f(0.0,1.0,0.0))
		end
		g_dead=false
	elseif (on_platform()~="") then--verifico si el personaje esta en una plataforma

		l_pos=l_pos+moving_on_platform(on_platform())
		
		l_player:set_position(l_pos)
		
	else
		--Sino se hace set de la posición determinada por 
		l_player:set_position(l_pos)
	end
	
	
	
	
	l_box_object:set_position(l_player:get_position())
	if(l_im:is_down(0,CInputManager.KEY_G)) then l_player:set_position(Vect3f(0.0,1.0,95.0)) end--para probar plataformas
	
end
--FIN DE FUNCIONES DE DESPLAZAMIENTO Y SALTO DE PERSONAJE

--FUNCIONES PARA REVISAR SI ESTAMOS SOBRE SUELO O AIRE
function floor_check()
	local l_player=core:get_renderable_objects_layers_manager():get_resource("solid"):get_instance("my_object")
	local l_box_object=core:get_renderable_objects_layers_manager():get_resource("solid"):get_instance("Box001")
	local l_box_pos=l_box_object:get_position()
	
	
	g_dead=off_floor(l_box_pos,"Mover",50,14)
	g_dead=g_dead and off_floor(l_box_pos,"Mover001",20,14)
	g_dead=g_dead and off_floor(l_box_pos,"Mover003",20,14)
	g_dead=g_dead and off_floor(l_box_pos,"PasilloEstrecho",10,0.5)
	g_dead=g_dead and off_floor(l_box_pos,"Mover004",20,14)
	g_dead=g_dead and off_floor(l_box_pos,"PlataformaMovil",8,14)
	g_dead=g_dead and off_floor(l_box_pos,"PlataformaMovil001",8,14)
	g_dead=g_dead and off_floor(l_box_pos,"Mover006",20,14)
	

end

--Función que recibe parámetros y calcula si el personaje esta sobre suelo o aire
function off_floor(obj_pos, floor_name, floor_length, floor_width)
	
	
	local l_floor_pos=core:get_renderable_objects_layers_manager():get_resource("solid"):get_instance(floor_name):get_position()
	
	local floor_zp_limit=l_floor_pos.z+(floor_length/2.0)
	local floor_zm_limit=l_floor_pos.z-(floor_length/2.0)
	local floor_xp_limit=l_floor_pos.x+(floor_width/2.0)
	local floor_xm_limit=l_floor_pos.x-(floor_width/2.0)
	
	if (((obj_pos.z>floor_zp_limit) or (obj_pos.z<floor_zm_limit) or (obj_pos.x>floor_xp_limit) or (obj_pos.x<floor_xm_limit)) and (g_bJumping==false)) then 
		
		return true	
	else
		
		return false
	end
	
end
--FIN DE FUNCIONES PARA REVISAR SI ESTAMOS EN SUELO O AIRE

--FUNCIONES PARA EL DESPLAZAMIENTO DEL PLAYER EN PLATAFORMA
function on_platform()
	local l_player=core:get_renderable_objects_layers_manager():get_resource("solid"):get_instance("my_object")
	
	if ((off_floor(l_player:get_position(),"PlataformaMovil",8,14)==false) and g_bJumping==false) then return "PlataformaMovil" end
	if ((off_floor(l_player:get_position(),"PlataformaMovil001",8,14)==false) and g_bJumping==false) then return "PlataformaMovil001"
	else 
		
		g_bOn_platform=false
		return "" 
	end
end

function moving_on_platform(platform_name)
	local l_player=core:get_renderable_objects_layers_manager():get_resource("solid"):get_instance("my_object")
	local l_platform=core:get_renderable_objects_layers_manager():get_resource("solid"):get_instance(platform_name)
	local l_const_platform_pos=l_platform:get_position()
	local l_platform_pos=Vect3f(l_const_platform_pos)
	if(g_bOn_platform==false) then 
		g_prev_platform_pos=l_platform_pos
		g_bOn_platform=true
	end
	local l_player_pos_offset=l_platform_pos-g_prev_platform_pos
	g_prev_platform_pos=l_platform_pos
	return l_player_pos_offset
	

end 
--FIN DE FUNCIONES PARA EL DESPLAZAMIENTO DEL PLAYER EN PLATAFORMA

function on_render_scripted_controller()

end

function on_create_scripted_controller()

end


function test_func2(a)
	local l_im=core:get_input_manager()

	if (l_im:is_up_down(0,CInputManager.KEY_N)) then --si c se presiona
		debug_lua(a)
	end
end

function test_func()
	local l_im=core:get_input_manager()
	
	local a=2
	
	if (l_im:is_up_down(0,CInputManager.KEY_T)) then --si c se presiona
		debug_lua(a)
	end
end
